package mole 
{
	import mole.entities.CPlayer;
	import mole.state.CGameOver;
	import flash.geom.Point;
	import flash.system.IMEConversionMode;
	import net.flashpunk.FP;
	/**
	 * Gestionnaire des régles de jeu.
	 * Continue, Nombre de vie, High Score, Point de respawn.
	 * @author Cédric Liaudet
	 */
	public class CGameRules 
	{
		static private const GAME_LOOP:int = 0;
		static private const GAME_END:int = 1;
		static private const GAME_MENU:int = 2;
		
		/**
		 * Constructeur par défaut.
		 */
		public function CGameRules() 
		{
			m_iContinue = 0;
			m_aPlayers = new Vector.<CPlayer>();
			m_RespawnPoint = new Point;
			
			m_iGameState = GAME_MENU;
		}
		
		public function GetWiner():String
		{
			return m_Winer;
		}
		
		/**
		 * Callback lorsqu'une partie commence.
		 */
		public function OnGameStart():void
		{				
			// On charge les paramètres de jeu.
			m_iContinue = 3;
			m_iGameState = GAME_LOOP;
		}
		
		/**
		 * Callback lorsque la partie est fini.
		 */
		public function OnGameEnd():void
		{			
			while (m_aPlayers.length)
				m_aPlayers.pop();
				
			Main.World.removeAll();
			Main.World.updateLists();
		}
		
		/**
		 * Callback lorsqu'un niveau commence.
		 */
		public function OnLevelStart():void
		{
			// On récupére le point de respawn de base du/des joueur(s)
			if (NbPlayers)
			{
				m_RespawnPoint.x = m_aPlayers[0].x;
				m_RespawnPoint.y = m_aPlayers[0].y;
			}
		}
		
		/**
		 * MAJ du gestionnaire.
		 */
		public function OnUpdate():void
		{
			// il n'y a plus de continue, game over
			if (m_iGameState == GAME_END)
			{
				m_iGameState = GAME_MENU;
				
				OnGameEnd();
				Main.GameStateManager.SetCurrentState(new CGameOver);
			}
		}
		
		/**
		 * On respawn le joueur spécifié.
		 * @param _iPlayerIndex Numéro de joueur.
		 * @param _bForceRespawn On force le respawn.
		 * @return true si le respawn a fonctionné.
		 */
		public function RespawnPlayer(_iPlayerIndex:int, _bForceRespawn:Boolean = false):Boolean
		{
			if (_iPlayerIndex < NbPlayers)
			{
				// On vérifie que le joueur est mort et qu'il est suffisament de continue.
				if (_bForceRespawn || (m_aPlayers[_iPlayerIndex].IsDead() && m_iContinue > 0))
				{
					m_iContinue--;
					m_aPlayers[_iPlayerIndex].Respawn(m_RespawnPoint);
					
					if (m_iContinue <= 0)
						m_iGameState = GAME_END;
					
					return true;
				}
			}
			
			return false;
		}
		
		/**
		 * Ajout un joueur.
		 */
		public function AddPlayer(_Player:CPlayer):void
		{
			if (_Player)
			{
				m_aPlayers.push(_Player);
			}
		}
		
		/**
		 * Suppression d'un joueur
		 */
		public function RemovePlayer(_Player:CPlayer):void
		{
			for (var i:int = 0; i < m_aPlayers.length; i++)
			{
				if (m_aPlayers[i] == _Player)
				{
					m_Winer = "P" + (_Player.GetId() + 1);
					if (i == 0)
						m_aPlayers.shift();
					else if (i == m_aPlayers.length - 1)
						m_aPlayers.pop();
					else
					{
						for (var j:int = i; j < m_aPlayers.length - 1; j++)
						{
							m_aPlayers[j] = m_aPlayers[j + 1];
						}
						
						m_aPlayers.pop();
					}
					
					break;
				}
			}
			
			// fin du jeu !
			if (m_aPlayers.length == 0)
			{
				m_iGameState = GAME_END;
			}
		}
		
		/**
		 * Définie le nouveau point de respawn.
		 * @param _iPosX Position sur l'axe des x.
		 * @param _iPosY Position sur l'axe des y.
		 */
		public function SetRespawnPoint(_iPosX:int, _iPosY:int):void
		{
			m_RespawnPoint.x = _iPosX;
			m_RespawnPoint.y = _iPosY;
		}
		
		public function GetPlayer(_nIndex:int):CPlayer { return m_aPlayers[_nIndex];}
		
		/**
		 * On récupére le nombre de joueur.
		 * @return le nombre de joueur.
		 */
		public function get NbPlayers():int { return m_aPlayers.length; }
		
		private var m_aPlayers:Vector.<CPlayer>; ///< Tableaux de joueur.
		private var m_iContinue:int;			 ///< Les continues.
		private var m_RespawnPoint:Point;		 ///< Position de respawn.
		private var m_iGameState:int;			 ///< Flag pour savoir si la partie est fini.
		private var m_Winer:String;
	}

}